import 'dart:async';

import 'package:get/get.dart';
import 'package:sudoku/util/RecordModel.dart';
import 'package:sudoku/util/global.dart';
import 'package:sudoku/util/sukodu/core.dart';
import 'package:sudoku/util/sukodu/generator.dart';
import 'package:sudoku/util/user_preferences.dart';
import 'package:sudoku/widget/PauseDialog.dart';
import 'package:sudoku/widget/ResetDialog.dart';
import 'package:sudoku/widget/WinDialog.dart';

class GameViewModel extends GetxController {
  final List<int> _originPuzzles = [];
  final puzzles = [].obs;
  final answers = [].obs;
  final chooseBoxIndex = 0.obs;
  final countDownNum = 0.obs;
  final remindNum = 2.obs;
  Timer? _timer;

  final LEVEL level;

  GameViewModel(this.level);

  @override
  onInit() {
    super.onInit();

    configPuzzle();
  }

  void configPuzzle() {
    Sudoku sudoku = Sudoku.generator(level);
    _originPuzzles.assignAll(sudoku.puzzle);
    puzzles.assignAll(sudoku.puzzle);
    answers.assignAll(sudoku.answer);

    // print(answers);

    countDownNum.value = 0;
    _cancelTimer();
    _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      countDownNum.value += 1;
    });
  }

  bool isOnlyReadBox(int index) => _originPuzzles[index] != -1;

  void fillBox(int num) {
    if (isOnlyReadBox(chooseBoxIndex.value)) {
      return;
    }

    puzzles[chooseBoxIndex.value] = num;

    if (answers[chooseBoxIndex.value] != num) {
      print("error");
    } else {
      if (isComplete) {
        success();
      }
    }
  }

  void clearItem() {
    if (isOnlyReadBox(chooseBoxIndex.value)) {
      return;
    }

    puzzles[chooseBoxIndex.value] = -1;
  }

  void remindClick() {
    if (isOnlyReadBox(chooseBoxIndex.value)) {
      return;
    }
    if (remindNum.value == 0) return;
    remindNum.value -= 1;
    puzzles[chooseBoxIndex.value] = answers[chooseBoxIndex.value];
    if (isComplete) {
      success();
    }
  }

  bool isCorrect(int index) {
    bool correct = false;
    if (isOnlyReadBox(index)) {
      correct = true;
    } else {
      if (puzzles[index] == answers[index]) {
        correct = true;
      } else {
        correct = false;
      }
    }
    return correct;
  }

  void resetClick() {
    showResetDialog().then((value) {
      if (value != null) {
        if (value) {
          configPuzzle();
        }
      }
    });
  }

  void pauseClick() {
    _cancelTimer();
    showPauseDialog(countDownNum.value).then((value) {
      if (value != null) {
        if (value == 1) {
          backHome();
        } else if (value == 2) {
          _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
            countDownNum.value += 1;
          });
        }
      }
    });
  }

  void success() {
    _cancelTimer();
    showWinDialog(countDownNum.value).then((value) {
      if (value == 1) {
        backHome();
      } else if (value == 2) {
        configPuzzle();
      }
    });

    RecordModel recordModel = RecordModel(
        id: DateTime.now().millisecondsSinceEpoch.toString(),
        type: LEVEL_TITLE[level],
        puzzle: _originPuzzles,
        duration: countDownNum.value,
        time: DateTime.now().millisecondsSinceEpoch);
    UserPreferences.addRecord(recordModel);
  }

  void backHome() {
    Get.back();
  }

  void _cancelTimer() {
    if (_timer != null) {
      _timer!.cancel();
      _timer = null;
    }
  }

  bool get isComplete {
    print(puzzles);
    for (int i = 0; i < puzzles.length; i++) {
      if (puzzles[i] != answers[i]) {
        return false;
      }
    }
    return true;
  }

  @override
  dispose() {
    super.dispose();
    _cancelTimer();
  }
}
